import logging
from random import randint

from django.http import HttpResponse, JsonResponse
from django.views import View
from django_redis import get_redis_connection
from libs.captcha.captcha import captcha
from utils.response_code import RETCODE

from .constants import IMAGE_CODE_EXPIRE, SMS_CODE_EXPIRE

# Create your views here.

logger = logging.getLogger(__name__)


class ImageCodeView(View):
    """处理图片验证码"""

    def get(self, request, uuid):
        # 获取图片验证码的文本和图片
        code, image = captcha.generate_captcha()
        conn = get_redis_connection()
        # 将图片验证码文本插入redis，并设置有效期
        conn.setex(uuid, IMAGE_CODE_EXPIRE, code)
        return HttpResponse(image, content_type='image/jpeg')


class SmsCodeView(View):
    """处理短信验证码"""

    def get(self, request, mobile, uuid, image_code):
        # 检查用户提交的信息是否完整，不完整就返回错误信息
        if not all((mobile, uuid, image_code)):
            return JsonResponse({"code": RETCODE.NECESSARYPARAMERR, "errmsg": "请检查手机号"})

        try:
            conn = get_redis_connection()
            redis_code = conn.get(uuid)
            conn.delete(uuid)
        except Exception as e:
            logger.error(e)
            return JsonResponse({"code": RETCODE.DBERR, "errmsg": "数据库错误"})
        else:
            # 检查获取到的值是否为空
            if redis_code == None:
                return JsonResponse({"code": RETCODE.IMAGECODEERR, "errmsg": "图片验证码过期"})
            # 检查用户输入的图片验证码是否正确
            if image_code.lower() != redis_code.decode("utf8").lower():  # redis的数据是bytes类型，需要解码
                return JsonResponse({"code": RETCODE.IMAGECODEERR, "errmsg": "图片验证码错误"})

        # 从redis查询该手机号是否在1分钟内获取过
        send_flag = conn.get('send_flag%s' % mobile)
        if send_flag:
            return JsonResponse({"code": RETCODE.THROTTLINGERR, "errmsg": "验证码请求太频繁"})

        # 随机生成验证码
        sms_code = "%06d" % randint(0, 999999)
        # 创建redis管道
        pipe = conn.pipeline()
        # 验证码保存到 redis，用手机号当作键
        pipe.setex(mobile, SMS_CODE_EXPIRE, sms_code)

        # 用delay方法将发送短信的任务添加到队列
        from celery_tasks.sms.tasks import send_sms_code
        send_sms_code.delay(mobile, sms_code)  # 将send_sms_code需要的参数传进去
        
        # 发送完短信，设置标志位，防止频繁请求短信验证码
        pipe.setex('send_flag%s' % mobile, 60, 1)
        # 执行管道中的多个指令
        pipe.execute()
        return JsonResponse({"code": RETCODE.OK, "errmsg": "OK"})
